#include "function_button_manager.h"
#include "../config/config.h"
#include "../config/cabrillo_config.h"
#include "../radio/radio_manager.h"
#include "../database/sqlite_manager.h"
#include "qso_edit_dialog.h"
#include <iostream>
#include <string>
#include <memory>
#include <stdexcept>
#include <array>
#include <cstdio>
#include <map>
#include <time.h>
#include <locale>
#include <algorithm>

// Global variables
extern std::map<std::string, std::map<std::string, std::string>> config;
extern BaseConfig baseConfig;
// 初始化静态变量
int FunctionButtonManager::QSOCount = 1;

std::string FunctionButtonManager::execute_command(const std::string& command) {
    std::array<char, 128> buffer;
    std::string result;
    std::unique_ptr<FILE, int (*)(FILE*)> pipe(popen(command.c_str(), "r"), pclose);
    if (!pipe) {
        throw std::runtime_error("popen() failed!");
    }
    while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) {
        result += buffer.data();
    }
    return result;
}

void FunctionButtonManager::stopSendCW() {
    // 调用RadioManager的stopSendThread函数来停止CW发送
    RadioManager::stopSendThread();
    std::cout << "已发送停止CW发送请求" << std::endl;
}

void FunctionButtonManager::on_function_button_clicked(GtkWidget *widget, gpointer data) {
    GtkBuilder *builder = GTK_BUILDER(data);
    
    // Get the button ID defined in Glade
    const gchar *button_id = gtk_buildable_get_name(GTK_BUILDABLE(widget));
    if (!button_id) {
        std::cerr << "无法获取按钮ID" << std::endl;
        return;
    }
    
    std::string button_name(button_id);
    // Extract the configuration key from the button ID
    // For example, "F1Button" -> "F1", "Fun1Button" -> "Fun1"
    std::string config_key = button_name;
    if (button_name.length() > 6 && button_name.substr(button_name.length() - 6) == "Button") {
        config_key = button_name.substr(0, button_name.length() - 6);
    }
    
    std::cout << "使用配置键: '" << config_key << "'" << std::endl;
    
    if(config_key.empty()) {
        std::cerr << "无效的配置键: '" << config_key << "'" << std::endl;
        return;
    }
    //如要是Fun开头的就是运行函数，否则是发送CW字符串，将字符串发送到CW键
    if (config_key.substr(0, 3) == "Fun") {
        // Execute function command，显示Fun?fun，fun是config_key的第3个字符开始的字符串
        // 使用CabrilloConfig获取CONTEST值替代原来的QSOType
        CabrilloConfig* cabrilloConfig = CabrilloConfig::getInstance();
        std::string contestType = cabrilloConfig->get("CabrilloConfig.CONTEST", "DX");
        std::string fun = config[contestType][config_key+"fun"];
        std::cout << "执行函数: " << fun << std::endl;
        
        if (fun == "FunOpenCWPort") {
            //如CW端口已经打开，就关闭它
            if (RadioManager::is_cw_port_open()) {
                RadioManager::close_cw_port();
                //修改CW配置按钮的文本为"打开CW端口"
                GtkWidget* cw_config_button = widget;
                if (cw_config_button) {
                    gtk_button_set_label(GTK_BUTTON(cw_config_button), "打开CW端口");
                } else {
                    std::cerr << "警告: 找不到CW配置按钮" << std::endl;
                }
                std::cout << "CW端口已关闭" << std::endl;
            }else{
                // 打开CW端口
                std::cout << "打开CW端口功能被调用" << std::endl;
                // 调用RadioManager的打开CW端口函数
                if(RadioManager::open_cw_port() == 0){
                    //修改产生点击事件的按钮的文本为"关闭CW端口"
                    //取得产生点击事件的按钮
                    GtkWidget* cw_config_button = widget;
                    if (cw_config_button) {
                        gtk_button_set_label(GTK_BUTTON(cw_config_button), "关闭CW端口");
                    } else {
                        std::cerr << "警告: 找不到CW配置按钮" << std::endl;
                    }
                    std::cout << "CW端口已打开" << std::endl;
                }
            }
            
        } else if (fun.substr(0, 9) == "FunQRZCom") {
            //调用MapWindow的open_map函数打开 |后面的字符串
            std::string url = fun.substr(fun.find("|") + 1);
            if (MainApp::mapWindowInstance) {
                 GtkWidget* edCallSign = GTK_WIDGET(gtk_builder_get_object(builder, "edCallSign"));
                std::string callSign = "";
                if (edCallSign) {
                    callSign = gtk_entry_get_text(GTK_ENTRY(edCallSign));
                } else {
                    std::cerr << "警告: 找不到edCallSign输入框" << std::endl;
                }
                MainApp::mapWindowInstance->open_map(url+"/"+callSign);
            }

        }else if (fun == "FunMap") {
            //从config中获取CabrilloConfig.GPS-LATITUDE和CabrilloConfig.GPS-LONGITUDE
            std::string cs_mylat = cabrilloConfig->get("CabrilloConfig.GPS-LATITUDE", "");
            std::string cs_mylon = cabrilloConfig->get("CabrilloConfig.GPS-LONGITUDE", "");

            //dxcc cty_dat中取得cs_lat和cs_lon
            double cs_lat = 0.0;
            double cs_lon = 0.0;
            //获取edCallSign控件
            GtkWidget* edCallSign = GTK_WIDGET(gtk_builder_get_object(builder, "edCallSign"));
            std::string callSign = "";
            if (edCallSign) {
                callSign = gtk_entry_get_text(GTK_ENTRY(edCallSign));
            } else {
                std::cerr << "警告: 找不到edCallSign输入框" << std::endl;
            }
            std::string callsignUpper = callSign;
            std::transform(callsignUpper.begin(), callsignUpper.end(), callsignUpper.begin(), ::toupper);
            const auto* info = MainApp::parser.lookupCountry(callsignUpper.c_str());
            if (info) {
                cs_lat = info->latitude;
                cs_lon = -info->longitude;
            } else {
                std::cerr << "警告: 无法找到callsignUpper的国家信息" << std::endl;
            }


            //调用MapWindow的open_map函数打开 |后面的字符串
            std::string url = "http://127.0.0.1:8001/3.html?param_lat1=" + cs_mylat 
            + "&param_lon1=" + cs_mylon 
            + "&param_lat2=" + std::to_string(cs_lat) 
            + "&param_lon2=" + std::to_string(cs_lon)
            + "&param_call=" + callSign
            + "&param_mysign=" + cabrilloConfig->get("CabrilloConfig.CALLSIGN", "");
            if (MainApp::mapWindowInstance) {
                MainApp::mapWindowInstance->open_map(url);
            }
        }else if (fun == "FunStop") {
            // 停止发送CW
            stopSendCW();
        } else if (fun == "FunSaveLog") {
            std::string date_str,time_str,band,mode,call,callsign, snt,rcv,name,memo,frequency;
            //callsign = edCallSign的文本
            GtkWidget* edCallSign = GTK_WIDGET(gtk_builder_get_object(builder, "edCallSign"));
            if (edCallSign) {
                callsign = gtk_entry_get_text(GTK_ENTRY(edCallSign));
            } else {
                std::cerr << "警告: 找不到edCallSign输入框" << std::endl;
            }
            //call= baseConfig call
            CabrilloConfig* cabrilloConfig = CabrilloConfig::getInstance();
            call = cabrilloConfig->get("CabrilloConfig.CALL", "");
            //band = config CurrentBand
            band = baseConfig.currentBand;
            mode = "CW";
            //snt = edSnt的文本
            GtkWidget* edSnt = GTK_WIDGET(gtk_builder_get_object(builder, "edSnt"));
            if (edSnt) {
                snt = gtk_entry_get_text(GTK_ENTRY(edSnt));
            } else {
                std::cerr << "警告: 找不到edSnt输入框" << std::endl;
            }
            //rcv = edRcv的文本
            GtkWidget* edRcv = GTK_WIDGET(gtk_builder_get_object(builder, "edRcv"));
            if (edRcv) {
                rcv = gtk_entry_get_text(GTK_ENTRY(edRcv));
            } else {
                std::cerr << "警告: 找不到edRcv输入框" << std::endl;
            }
            //name = edName的文本
            GtkWidget* edName = GTK_WIDGET(gtk_builder_get_object(builder, "edName"));
            if (edName) {
                name = gtk_entry_get_text(GTK_ENTRY(edName));
            } else {
                std::cerr << "警告: 找不到edName输入框" << std::endl;
            }
            //memo = edMemo的文本
            GtkWidget* edMemo = GTK_WIDGET(gtk_builder_get_object(builder, "edMemo"));
            if (edMemo) {
                memo = gtk_entry_get_text(GTK_ENTRY(edMemo));
            } else {
                std::cerr << "警告: 找不到edMemo输入框" << std::endl;
            }
            //定义 frequency = edFrequency的文本
            GtkWidget* edFrequency = GTK_WIDGET(gtk_builder_get_object(builder, "edFrequency"));
            if (edFrequency) {
                frequency = gtk_entry_get_text(GTK_ENTRY(edFrequency));
            } else {
                std::cerr << "警告: 找不到edFrequency输入框" << std::endl;
            }
            //date time ＝ 系统当前时间转UTC时间字符串，格式yyyy-mm-dd hh:mm
            //获取系统当前时间
            time_t now = time(0);
            //转换为yyyy-mm-dd hh:mm格式
            struct tm *local_time = localtime(&now);
            // 转换为UTC时间
            time_t utc_time = mktime(local_time);
            // 转换为UTC时间字符串
            local_time = gmtime(&utc_time);
            char date_buffer[20];
            char time_buffer[10];
            strftime(date_buffer, sizeof(date_buffer), "%Y-%m-%d", local_time);
            strftime(time_buffer, sizeof(time_buffer), "%H:%M", local_time);
            date_str = date_buffer;
            time_str = time_buffer;
            std::cout << "date: " << date_str 
                    << "time: " << time_str 
                    << "band: " << band 
                    << "frequency: " << frequency
                    << "mode: " << mode 
                    << "call: " << call 
                    << "callsign: " << callsign 
                    << "snt: " << snt 
                    << "rcv: " << rcv 
                    << "name: " << name 
                    << "memo: " << memo << std::endl;
            // 保存日志
            saveLog(date_str,time_str,band,frequency,mode,call,callsign, snt,rcv,name,memo);
        } 
        else if (fun == "FunEdit"){
            //调用编辑对话框qso_edit_dialog编辑数据
            // 首先判断log_grid_dialog是否已经创建
            if (MainApp::isLogWindowCreated() && MainApp::getLogWindowInstance()) {
                // 获取log_grid_dialog的当前选中行数据
                LogGridDialog* logGridDialog = MainApp::getLogWindowInstance();
                QSORecord record;
                
                // 尝试获取选中的记录
                if (logGridDialog->get_selected_record(record)) {
                    // 创建并显示编辑对话框
                    QSOEditDialog *editDialog = new QSOEditDialog();
                    if (editDialog->init(record)) {
                        editDialog->show();
                    } else {
                        std::cerr << "无法初始化编辑对话框" << std::endl;
                        delete editDialog;
                    }
                } else {
                    std::cout << "没有选中任何行，创建空的记录" << std::endl;
                    // 如果没有选中行，创建一个空的QSORecord对象用于编辑
                    QSOEditDialog *editDialog = new QSOEditDialog();
                    QSORecord emptyRecord;
                    if (editDialog->init(emptyRecord)) {
                        editDialog->show();
                    } else {
                        std::cerr << "无法初始化编辑对话框" << std::endl;
                        delete editDialog;
                    }
                }
            } else {
                std::cout << "log_grid_dialog未创建，创建空的记录" << std::endl;
                // 如果log_grid_dialog未创建，创建一个空的QSORecord对象用于编辑
                QSOEditDialog *editDialog = new QSOEditDialog();
                QSORecord record;
                if (editDialog->init(record)) {
                    editDialog->show();
                } else {
                    std::cerr << "无法初始化编辑对话框" << std::endl;
                    delete editDialog;
                }
            }
        }
        else if (fun == "FunWipe") {
            // 清除输入框内容
            GtkBuilder *builder = UIManager::get_builder();
            if (builder) {
                MainApp::clear_input_fields(builder);
            }
            //edCallSign获得焦点
            GtkWidget* edCallSign = GTK_WIDGET(gtk_builder_get_object(builder, "edCallSign"));
            if (edCallSign) {
                gtk_widget_grab_focus(edCallSign);
            } else {
                std::cerr << "警告: 找不到edCallSign输入框" << std::endl;
            }
        }

    } else {
        // Send CW string 显示F？CW字符串
        //取CW串，从config_key的第3个字符开始
        // 使用CabrilloConfig获取CONTEST值替代原来的QSOType
        CabrilloConfig* cabrilloConfig = CabrilloConfig::getInstance();
        std::string contestType = cabrilloConfig->get("CabrilloConfig.CONTEST", "DX");
        std::string cw_str = config[contestType][config_key+"CW"];
        //如果CW字符串为空，就不发送
        if(cw_str.empty()) {
            std::cerr << "警告: 配置中未定义CW字符串: " << config_key << "CW" << std::endl;
            return;
        }        
        //发送CW码
        sendCW(builder, cw_str);
    }
    //edCallSign获得焦点
    GtkWidget* edCallSign = GTK_WIDGET(gtk_builder_get_object(builder, "edCallSign"));
    if (edCallSign) {
        gtk_widget_grab_focus(edCallSign);
    } else {
        std::cerr << "警告: 找不到edCallSign输入框" << std::endl;
    }
}

void FunctionButtonManager::writeToQSOMemo(GtkBuilder *builder, const std::string& message) {
    // 获取edQSOMemo控件
    GtkWidget* edQSOMemo = GTK_WIDGET(gtk_builder_get_object(builder, "edQSOMemo"));
    if (!edQSOMemo) {
        std::cerr << "警告: 找不到edQSOMemo输入框" << std::endl;
        return;
    }
    
    // 获取文本缓冲区
    GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(edQSOMemo));
    if (!buffer) {
        std::cerr << "无法获取edQSOMemo的文本缓冲区" << std::endl;
        return;
    }
    
    // 将消息添加到edQSOMemo
    gtk_text_buffer_insert_at_cursor(buffer, message.c_str(), -1);
    
    // 滚动到末尾
    GtkTextIter end_iter;
    gtk_text_buffer_get_end_iter(buffer, &end_iter);
    gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(edQSOMemo), &end_iter, 0.0, FALSE, 0, 0);
}

int FunctionButtonManager::replaceCWStr(GtkBuilder *builder, std::string& cw_str) {
    //edCallSign获得焦点
    GtkWidget* edCallSign = GTK_WIDGET(gtk_builder_get_object(builder, "edCallSign"));
            
    if(cw_str == "{CMDWIPE}"){
        // 清除输入框内容
        GtkBuilder *builder = UIManager::get_builder();
        if (builder) {
            MainApp::clear_input_fields(builder);
        }
        if (edCallSign) {
            gtk_widget_grab_focus(edCallSign);
        } else {
            writeToQSOMemo(builder, "警告: 找不到edCallSign输入框" );
        }
        return -1;
    }
    //如果CALLSIGN为空，就不发送
    CabrilloConfig* cabrilloConfig = CabrilloConfig::getInstance();
    std::string mySign = cabrilloConfig->get("CabrilloConfig.CALLSIGN", "未设置");
    std::string myName = cabrilloConfig->get("CabrilloConfig.NAME", "未设置");
    
    std::string name ="";
    GtkWidget* edName = GTK_WIDGET(gtk_builder_get_object(builder, "edName"));
    if (edName) {
        name = gtk_entry_get_text(GTK_ENTRY(edName));
    }
    if(mySign == "未设置") {
        writeToQSOMemo(builder, "警告: 配置中未定义CALLSIGN" );
        return -1;
    }
    if(myName == "未设置"){
        writeToQSOMemo(builder,  "警告: 配置中未定义NAME" );
    }
    if(cw_str.find("{CALL}") != std::string::npos) {
        //取得 edCallSign的值，如果为空，则退出
        GtkWidget* edCallSign = GTK_WIDGET(gtk_builder_get_object(builder, "edCallSign"));
        if (!edCallSign) {
            std::cerr << "警告: 找不到edCallSign输入框" << std::endl;
            return -1;
        }
        std::string callSign = gtk_entry_get_text(GTK_ENTRY(edCallSign));
        if(callSign.empty()) {
            writeToQSOMemo(builder, "警告: edCallSign输入框为空" );
            // edCallSign 获取焦点
            gtk_widget_grab_focus(edCallSign);
            return -1;
        }
        //将CW字符串中的所有的{CALL}替换为edCallSign的值
        size_t pos = cw_str.find("{CALL}");
        while (pos != std::string::npos) {
            cw_str.replace(pos, 6, callSign);
            pos = cw_str.find("{CALL}", pos + callSign.length());
        }
    }
    if(cw_str.find("{RST}") != std::string::npos) {
        //取得 edSnt的值，如果为空，则退出
        GtkWidget* edSnt = GTK_WIDGET(gtk_builder_get_object(builder, "edSnt"));
        if (!edSnt) {
            std::cerr << "警告: 找不到edSnt输入框" << std::endl;
            return -1;
        }
        std::string rst = gtk_entry_get_text(GTK_ENTRY(edSnt));
        if(rst.empty()) {
            writeToQSOMemo(builder, "警告: edSnt输入框为空" );
            // edSnt 获取焦点
            gtk_widget_grab_focus(edSnt);
            return -1;
        }
        //将CW字符串中的所有的{RST}替换为edSnt的值
        size_t pos = cw_str.find("{RST}");
        while (pos != std::string::npos) {
            cw_str.replace(pos, 5, rst);
            pos = cw_str.find("{RST}", pos + rst.length());
        }

        //查找 有没有 {SRST},如果有且edSnt=599,就替换为5NN，否则替换 为edSnt的值
        pos = cw_str.find("{SRST}");
        while (pos != std::string::npos) {
            if(rst == "599") {
                cw_str.replace(pos, 6, "5NN");
            } else {
                cw_str.replace(pos, 6, rst);
            }
            pos = cw_str.find("{SRST}", pos + rst.length());
        }

    }
    if(cw_str.find("{RCV}") != std::string::npos) {
        //取得 edRCV的值，如果为空，则退出
        GtkWidget* edRCV = GTK_WIDGET(gtk_builder_get_object(builder, "edRcv"));
        if (!edRCV) {
            std::cerr << "警告: 找不到edRcv输入框" << std::endl;
            return -1;
        }
        std::string rcv = gtk_entry_get_text(GTK_ENTRY(edRCV));
        if(rcv.empty()) {
            writeToQSOMemo(builder,"警告: edRcv输入框为空");
            // edRcv 获取焦点
            gtk_widget_grab_focus(edRCV);
            return -1;
        }
        //将CW字符串中的所有的{RCV}替换为edRcv的值
        size_t pos = cw_str.find("{RCV}");
        while (pos != std::string::npos) {
            cw_str.replace(pos, 5, rcv);
            pos = cw_str.find("{RCV}", pos + rcv.length());
        }
        //查找 有没有 {SRCV},如果有且edRcv=599,就替换为5NN，否则替换 为edRcv的值
        pos = cw_str.find("{SRCV}");
        while (pos != std::string::npos) {
            if(rcv == "599") {
                cw_str.replace(pos, 6, "5NN");
            } else {
                cw_str.replace(pos, 6, rcv);
            }
            pos = cw_str.find("{SRCV}", pos + rcv.length());
        }
    }
    //将CW字符串中的所有的{CALLSIGN}替换为我的CALLSIGN
    size_t pos = cw_str.find("{CALLSIGN}");
    while (pos != std::string::npos) {
        cw_str.replace(pos, 10, mySign);
        pos = cw_str.find("{CALLSIGN}", pos + mySign.length());
    }       
    //判断其中有没有 {TIME},如果有，根据当前时间，6－12点替换为GM,12-18点替换为GA,18-24点替换为GE，0－6替换为GN
    pos = cw_str.find("{TIME}");
    if (pos != std::string::npos) {
        std::time_t now = std::time(nullptr);
        std::tm* localTime = std::localtime(&now);
        int hour = localTime->tm_hour;
        std::string timeStr = (hour >= 6 && hour < 12) ? "GM" :
                                (hour >= 12 && hour < 18) ? "GA" :
                                (hour >= 18 && hour < 24) ? "GE" : "GN";
        cw_str.replace(pos, 6, timeStr);
    }
    //如果其中有{NUM},就替换为QSOCount的值
    pos = cw_str.find("{NUM}");
    if (pos != std::string::npos) {
        std::string numStr = std::to_string(QSOCount);
        cw_str.replace(pos, 5, numStr);
    }
    pos = cw_str.find("{MYNAME}");
    if (pos != std::string::npos) {
        cw_str.replace(pos, 8, myName);
    }
    pos = cw_str.find("{NAME}");
    if (pos != std::string::npos) {
        cw_str.replace(pos, 6, name);
    }
    return 1;
}

void FunctionButtonManager::sendCW(GtkBuilder *builder, const std::string& cwStr) {
    std::string cw_str = cwStr;
    int ret = replaceCWStr(builder, cw_str);
    if(ret != 1) {
        return;
    }
    // TODO 需要完善 num增加逻辑，目前只是简单替换，后续需要根据实际情况调整
    // QSOCount++;
    //发送CW码
    RadioManager::send_cw(cw_str);
    
    //edCallSign获得焦点
    GtkWidget* edCallSign = GTK_WIDGET(gtk_builder_get_object(builder, "edCallSign"));
    if (edCallSign) {
        gtk_widget_grab_focus(edCallSign);
    } else {
        std::cerr << "警告: 找不到edCallSign输入框" << std::endl;
    }
}

void FunctionButtonManager::saveLog(const std::string& date, const std::string& time, const std::string& band, 
                                   const std::string& frequency, const std::string& mode, const std::string& call, const std::string& callsign,
                                   const std::string& snt, const std::string& rcv, const std::string& name, 
                                   const std::string& memo) {
    // 获取SQLiteManager单例实例
    SQLiteManager& dbManager = SQLiteManager::getInstance();
    
    // 连接数据库（如果尚未连接）
    if (!dbManager.connect()) {
        std::cerr << "无法连接到数据库" << std::endl;
        return;
    }
    
    // 创建QSO记录对象
    QSORecord record;
    record.date = date;
    record.time = time;
    record.callsign = callsign;
    record.band = band;
    record.frequency = frequency;
    record.mode = mode;
    record.rst_sent = snt;
    record.rst_rcvd = rcv;
    record.name = name;
    record.qth = "";  // QTH字段暂时为空
    record.memo = memo;
    record.data = "";  // data字段不保存，保持为空
    record.log_creation_date = date + " " + time;  // 日志创建日期
    
    // 获取当前时间作为记录创建和修改时间
    std::time_t now = std::time(nullptr);
    char time_buffer[20];
    std::strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%d %H:%M:%S", std::localtime(&now));
    std::string current_time = time_buffer;
    record.record_create_time = current_time;
    record.record_modify_time = current_time;
    
    // 插入记录到数据库
    if (dbManager.insertQSO(record)) {
        std::cout << "QSO记录保存成功" << std::endl;
        
        // 刷新日志网格对话框的数据（如果已创建）
        if (MainApp::isLogWindowCreated()) {
            MainApp::refreshLogWindowData();
        }
    } else {
        std::cerr << "QSO记录保存失败" << std::endl;
    }
}